<!DOCTYPE html>
<html><head>
  <title>WebGL Path Tracing</title>
  <style type="text/css"><!--

body {
  max-width: 900px;
  padding: 30px;
  margin: 0 auto;
  font: 14px/19px 'Lucida Grande', sans-serif;
}

#main {
  margin: 80px 0;
  padding-left: 542px;
  height: 512px;
  position: relative;
}

#error {
  position: absolute;
  left: 0;
  top: 0;
  width: 412px;
  height: 412px;
  padding: 50px;
  text-align: center;
  background: #DFDFDF;
}

canvas {
  position: absolute;
  left: 0;
  top: 0;
}

p, ul {
  margin: 0 0 30px 0;
}

h1 {
  font: bold italic 50px Georgia;
  margin: 0 0 60px 0;
  text-align: center;
}

a {
  color: inherit;
}

#footer {
  text-align: center;
  margin: 100px 0 0 0;
}

#glossiness-factor {
  display: none;
  font-size: 12px;
}

#glossiness-factor input {
  width: 40px;
  text-align: center;
}

  --></style>
<script>var Stats=function(){function h(a){c.appendChild(a.dom);return a}function k(a){for(var d=0;d<c.children.length;d++)c.children[d].style.display=d===a?"block":"none";l=a}var l=0,c=document.createElement("div");c.style.cssText="position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000";c.addEventListener("click",function(a){a.preventDefault();k(++l%c.children.length)},!1);var g=(performance||Date).now(),e=g,a=0,r=h(new Stats.Panel("FPS","#0ff","#002")),f=h(new Stats.Panel("MS","#0f0","#020"));
if(self.performance&&self.performance.memory)var t=h(new Stats.Panel("MB","#f08","#201"));k(0);return{REVISION:16,dom:c,addPanel:h,showPanel:k,begin:function(){g=(performance||Date).now()},end:function(){a++;var c=(performance||Date).now();f.update(c-g,200);if(c>e+1E3&&(r.update(1E3*a/(c-e),100),e=c,a=0,t)){var d=performance.memory;t.update(d.usedJSHeapSize/1048576,d.jsHeapSizeLimit/1048576)}return c},update:function(){g=this.end()},domElement:c,setMode:k}};
Stats.Panel=function(h,k,l){var c=Infinity,g=0,e=Math.round,a=e(window.devicePixelRatio||1),r=80*a,f=48*a,t=3*a,u=2*a,d=3*a,m=15*a,n=74*a,p=30*a,q=document.createElement("canvas");q.width=r;q.height=f;q.style.cssText="width:80px;height:48px";var b=q.getContext("2d");b.font="bold "+9*a+"px Helvetica,Arial,sans-serif";b.textBaseline="top";b.fillStyle=l;b.fillRect(0,0,r,f);b.fillStyle=k;b.fillText(h,t,u);b.fillRect(d,m,n,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d,m,n,p);return{dom:q,update:function(f,
v){c=Math.min(c,f);g=Math.max(g,f);b.fillStyle=l;b.globalAlpha=1;b.fillRect(0,0,r,m);b.fillStyle=k;b.fillText(e(f)+" "+h+" ("+e(c)+"-"+e(g)+")",t,u);b.drawImage(q,d+a,m,n-a,p,d,m,n-a,p);b.fillRect(d+n-a,m,a,p);b.fillStyle=l;b.globalAlpha=.9;b.fillRect(d+n-a,m,a,e((1-f/v)*p))}}};"object"===typeof module&&(module.exports=Stats);
</script>
  
  <script type="text/javascript" src="glUtils.js"></script>
  <script type="text/javascript" src="rayTracing.js"></script>
</head>


<body>

  <h1>WebGL Path Tracing</h1>
  <h1>With Spatial-Temporal Denoiser</h1>

  <ul>
    <li>Select an object by clicking on it</li>
    <li>Move the selection along the face of its selection box by dragging around on that face</li>
    <li>Rotate the camera by dragging the background</li>
    <li>Delete the selection using the backspace key</li>
    <li>Toggle the denoiser to see the difference</li>
  </ul>

  <div id="main">
    <canvas id="canvas" width="512" height="512"></canvas>
    <div id="error"><noscript>Please enable JavaScript.</noscript></div>

    <p>
      <button onclick="javascript:ui.selectLight()">Select Light</button>
      <button onclick="javascript:ui.addSphere()">Add Sphere</button>
      <button onclick="javascript:ui.addCube()">Add Cube</button>
    </p>

    <p>
      <b>Material:</b>
      <select id="material">
        <option value="0" selected>Diffuse</option>
        <option value="1">Mirror</option>
        <option value="2">Glossy</option>
      </select>
      <span id="glossiness-factor">
        <br>with glossiness factor: 0 &lt; <input id="glossiness" value="0.6"> &lt; 1
      </span>
      <br>

      <b>Environment:</b>
      <select id="environment">
        <option value="0" selected>Cornell Box - Yellow and Blue</option>
        <option value="1">Cornell Box - Red and Green</option>
      </select>
    </p>

    <p>
      <b>Load preset scene:</b>
      <br><button onclick="javascript:ui.setObjects(makeSphereColumn())">Sphere Column</button>
      <br><button onclick="javascript:ui.setObjects(makeSpherePyramid())">Sphere Pyramid</button>
      <br><button onclick="javascript:ui.setObjects(makeSphereAndCube())">Sphere and Cube</button>
      <br><button onclick="javascript:ui.setObjects(makeCubeAndSpheres())">Cube and Spheres</button>
      <br><button onclick="javascript:ui.setObjects(makeTableAndChair())">Table and Chair</button>
      <br><button onclick="javascript:ui.setObjects(makeStacks())">Stacks</button>
    </p>

    <p>
      <b>Denoiser:</b>
      <select id="denoise">
        <option value="0" selected>spatial-temporal</option>
        <option value="1">temporal only</option>
        <option value="2">off</option>
      </select>
    </p>
  </div>

  <p> <a href="https://github.com/evanw/webgl-path-tracing">Path Tracer Made by Evan Wallace in 2010</a> </p>
  <p> <a href="https://github.com/1999foxes/raytrace_denoiser">Denoiser Made by 1999foxes in 2021</a> </p>


</body></html>